import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:gif/gif.dart';
import 'package:gongge/config/AppConst.dart';
import 'package:gongge/pages/HomePage.dart';
import 'package:gongge/routers/router.dart';
import 'package:gongge/utils/AudioUtils.dart';
import 'package:gongge/utils/SpUtils.dart';
import '../bean/PopBean.dart';
import '../game/block.dart';
import '../generated/l10n.dart';
import '../utils/ PanPageRouteBuilder.dart';
import '../utils/ClickUtils.dart';
import '../utils/GamePageUtils.dart';
import '../bean/BlockBean.dart';
import '../utils/CommUtils.dart';
import '../wight/Brik.dart';
import 'dart:math' as math;
import '../wight/My.dart';
import 'GamePage.dart';

///总行数
const GAME_PAD_MATRIX_H = 9;

///总列数
const GAME_PAD_MATRIX_W = 9;

//新手教程
class SplishPage extends StatefulWidget {
  bool isContinue = false; //true继续游戏的话
  SplishPage({Key? key, this.isContinue = false}) : super(key: key);
  @override
  State<SplishPage> createState() => SplishPageState();
}

///所有数据
List<List<BlockBean>> _data = [];
//给将要满足消分的方格添加蒙版，
List<List<BlockBean>> mengdata = [];
//三个随机模块
List<Block> _randowList = [];

//棋牌背景图左右内边距
const double bgPaddingSize = 10;

//棋盘内边距
double checkerboardSizeLeft = 10;

//棋盘方格默认背景
const String defaultBg = "assets/images/default_square.png";
//棋盘方格特殊背景
const String specialBg = "assets/images/special_square.png";

//放入棋盘后的声音
const inputboardList = [
  "jj_plus_spins_v1.mp3",
  "jj_plus_spins_v2.mp3",
  "jj_plus_spins_v3.mp3",
  "jj_plus_spins_v4.mp3",
  "jj_plus_spins_v5.mp3",
  "jj_plus_spins_v6.mp3",
  "jj_plus_spins_v7.mp3",
  "jj_plus_spins_v8.mp3",
  "jj_plus_spins_v9.mp3",
];

//消除分的声音
const getSoreList = [
  "get_sore1.mp3",
  "get_sore2.mp3",
  "get_sore3.mp3",
  "get_sore4.mp3",
  "get_sore5.mp3",
  "get_sore6.mp3",
];

class SplishPageState extends State<SplishPage>
    with SingleTickerProviderStateMixin {
  int? CurrentLevel = 1;
  @override
  void initState() {
    _data.clear();
    CurrentLevel = SpUtils.getInstance()?.getInt2(AppConst.fisrt);
    //新游戏
    //inflate game pad data
    startNewGame();
    super.initState();
  }



  bool? isFisrtVociePlay = false; //true播放了音乐

  //开始新游戏
  void startNewGame() {
    _data.clear();
    _randowList.clear();
    mengdata.clear();
   // print("当前等级是多少${CurrentLevel}");
    for (int i = 0; i < GAME_PAD_MATRIX_H; i++) {
      List<BlockBean> _newdata = [];

      for (int j = 0; j < GAME_PAD_MATRIX_W; j++) {
        BlockBean bean = BlockBean();
        //前3横排
        if (i >= 0 && i <= 2) {
          //中3竖排
          if (j >= 3 && j <= 5) {
            bean.defaultImg = specialBg;
          } else {
            bean.defaultImg = defaultBg;
          }
          //中3横排
        } else if (i >= 3 && i <= 5) {
          //前3竖排
          if (j >= 0 && j <= 2) {
            bean.defaultImg = specialBg;
          } else if (j >= 6 && j <= 8) {
            //后三竖排
            bean.defaultImg = specialBg;
          } else {
            //中3竖排
            bean.defaultImg = defaultBg;
          }
          //后3横排
        } else if (i >= 6 && i <= 8) {
          //横排
          if (j >= 3 && j <= 5) {
            bean.defaultImg = specialBg;
          } else {
            bean.defaultImg = defaultBg;
          }
        } else {
          bean.defaultImg = defaultBg;
        }

        if (CurrentLevel == 1) {
          if (i == 4 && j != 4) {
            bean.normal = 1;
            bean.img = "assets/images/square.png";
          }
        } else if (CurrentLevel == 2) {
          if (j == 4 && i != 4) {
            bean.normal = 1;

            bean.img = "assets/images/square.png";
          }
        } else if (CurrentLevel == 3) {
          if (i >= 3 && i <= 5 && j >= 3 && j <= 5) {
            bean.normal = 1;
            bean.img = "assets/images/square.png";
          }
        }

        if (i == 4 && j == 4) {
          bean.normal = 2;
          bean.eliminationEffect = 2;
        }

        _newdata.add(bean);
      }

      _data.add(_newdata);
    }

    //获取随机三个模块
    getRoundList();
    //如果数组里的元素是int或者String，用List.from是没问题的。深拷贝
    mengdata = CommUtils.copyWithList(_data);
  }

  bool isEndGame = false; //true结束游戏
/**
 * 查询是否有不满足填充情况的随机木块 isreduction=true时，当开始不满足填充时，到被消分后，有可能就满足填充了，所以这里需要处理一下。
 */
  void qrueyUnableTOfill(bool isreduction) {
    var qruey = GamePageUtils.qruey(_randowList, _data, rondowRemowMap);
    // print("查询出${qruey.length}");
    //下方方块显示的数量=总随机方块-被隐藏的数量
    int showCount = _randowList.length - rondowRemowMap.length;
    //  print("剩多少个还在显示${showCount}");
    //无法拖动的数量
    int noDragCount = 0;
    for (int i = 0; i < _randowList.length; i++) {
      if (qruey[i] != null) {
        // print("当前无法拖动positon${i}");
        //证明此下方的postop是不满足填充情况的
        for (var item in _randowList[i].shape) {
          for (var item2 in item) {
            if (item2.normal == 1) {
              item2.normal = 2;
            }
          }
        }
        noDragCount = noDragCount + 1;

        _randowList[i].drag = 1; //不允许拖动

      } else {
        if (isreduction && rondowRemowMap[i] == null) {
          print("当前变更的positon${i}");
          _randowList[i].drag = 0; //允许拖动
          for (var item in _randowList[i].shape) {
            for (var item2 in item) {
              if (item2.normal != 0) {
                item2.normal = 1;
              }
            }
          }
        }
      }
    }
  }

  Offset offsetA = Offset(0, 0); //按钮的初始位置

  GlobalKey anchorKey = GlobalKey();
  GlobalKey anchorKey2 = GlobalKey();

  /**
   * 手动监听物理返回键
   */
  Future<bool> _requestPop() {
    // if (Navigator.canPop(context)) {
    //   if (!isEndGame) {
    //     Navigator.pop(context);
    //   }
    // } else {
    //   if (!isEndGame) {
    //     SystemNavigator.pop();
    //   }
    // }
    return Future.value(!isEndGame);
  }

  @override
  Widget build(BuildContext context) {
    Size size = CommUtils.getSize(context);
    double width = CommUtils.getWidth(context);
    double hight = CommUtils.getHeight(context);
    return Scaffold(
      body: Container(
        width: width,
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage('assets/images/bg.png'),
            fit: BoxFit.fill,
          ),
        ),
        child: Stack(
          children: [
            //第一次Gif有延迟，所以这里预加载
            Gif(
              width: 0,
              height: 0,
              image: AssetImage(
                "assets/gif/1xg.gif",
              ),
              autostart: Autostart.once,
            ),
            Padding(
              padding: EdgeInsets.only(left: width * 0.02, right: width * 0.02),
              child: Column(
                children: [
                  Image.asset('assets/images/top_leaves.png',
                      width: double.infinity, fit: BoxFit.fill),

                  SizedBox(
                    height: size.height * 0.02,
                  ),
                  Align(
                    alignment: Alignment.center,
                    child: CommUtils.getTextGame(context, 20,
                        S.of(context).novice_tutorial, textColor, textbgColor),
                  ),
                  //顶部getCheckerboard()

                  Expanded(
                    child: SingleChildScrollView(
                      child: getCheckerboard(),
                    ),
                  )
                ],
              ),
            ),
            Stack(
              children: addshow.map((list) {
                return Positioned(
                  left: list.offset!.dx,
                  bottom: list.offset!.dy+10,
                  child: Gif(
                    width: size.width ,
                    height: size.width * 1.2,
                    image: AssetImage(
                      "assets/gif/1xg.gif",
                    ),
                    autostart: Autostart.once,
                  ),
                );
              }).toList(),
            ),
            Align(
              alignment: Alignment.bottomCenter,
              child: Image.asset('assets/images/botton_.png',
                  width: double.infinity,
                  height: hight * 0.09,
                  fit: BoxFit.fill),
            )
          ],
        ),
      ),
    );
  }

  /**
     * 棋盘布局
     */
  GlobalKey rootWidgetKey = GlobalKey();
  Widget getCheckerboard() {
    final size = MediaQuery.of(context).size;
    final width = size.width;
    final height = size.height;
    checkerboardSizeLeft = width * 0.027;
    //需要截图的布局
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        getTop(width, height),
        Row(
           mainAxisAlignment: MainAxisAlignment.center,
          children: [
            //棋盘
            Container(
              decoration: BoxDecoration(
                image: DecorationImage(
                  image: AssetImage('assets/images/checkerboard.png'),
                  fit: BoxFit.contain,
                ),
              ),
              alignment: Alignment.center,
              child: Padding(
                padding: EdgeInsets.only(
                    top: height * 0.01,
                    bottom: height * 0.02, //如果Container上面设置了高度，这离没用了
                    left: checkerboardSizeLeft,
                    right: width * 0.03),
                child: Column(

                  key: anchorKey,
                  children: _data
                      .asMap()
                      .map((i, e) {
                        return MapEntry(
                            i,
                            Row(
                              children: e
                                  .asMap()
                                  .map((i2, e) {
                                    return MapEntry(
                                        i2,
                                        BackgroundBrik.normal(
                                          e,
                                          bgChangelist,
                                          scoreChangelist,
                                          false,
                                          i,
                                          i2,
                                        ));
                                  })
                                  .values
                                  .toList(),
                            ));
                      })
                      .values
                      .toList(),
                ),
              ),
            ),

            CommUtils.getISWidth(width, height)
                ? Expanded(
                    child: SingleChildScrollView(
                    scrollDirection: Axis.horizontal,
                    child: Container(
                       width:   500,
                      decoration: BoxDecoration(
                        image: DecorationImage(
                          image: AssetImage(
                              'assets/images/checkerboard_bottom.png'),
                          fit: BoxFit.fill,
                        ),
                      ),
                      alignment: Alignment.center,
                      child: _createGridView(height, width),
                    ),
                  ))
                : Text("")
          ],
        ),
        CommUtils.getISWidth(width, height)
            ? Text("")
            : Stack(
                children: [
                  GamePageUtils().getCheckBooton(height),
                  _createGridView(height, width),
                ],
              )
      ],
    );
  }



  /// 打字机效果。持续时间为6秒的动画控制器  展示不用， 不然不是多语言效果
  late final AnimationController _controller = AnimationController(
    vsync: this,
    duration: const Duration(seconds: 6),
  )..forward();
  late final Animation<String> _animation =
      TextTween(end: lists).animate(_controller);

  String? lists = S.current.put_drag_in;
  Widget getTop(double width, double height) {
    return //顶部提示
        Container(
      margin: EdgeInsets.only(
          left: width * 0.025, right: width * 0.025, bottom: width * 0.015),
      padding: EdgeInsets.only(
        left: width * 0.025,
        right: width * 0.025,
      ),
      height: height * 0.06,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.all(Radius.circular(10)),
        color: Color(0Xff82000000),
      ),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Expanded(
            child: Center(
              child: Text(
                S.of(context).put_drag_in,
                style: const TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                  color: Colors.white,
                ),
              ),
            ),
          ),
          GestureDetector(
            onTap: () {
              if (ClickUtils.checkClick()) {
                AudioUtils.getInstance()?.play("seting_.mp3");
                Navigator.pop(context);
                SpUtils.getInstance()?.setInt(AppConst.fisrt, 5);
                Navigator.push(
                    context,
                    PanPageRouteBuilder(
                        builder: (context) => HomePage(),
                        popDirection: AxisDirection.down));
              }
            },
            child: Container(
              padding: EdgeInsets.only(left: width * 0.02, right: width * 0.02),
              margin:
                  EdgeInsets.only(top: height * 0.01, bottom: height * 0.005),
              width: width * 0.22,
              height: height * 0.075,
              decoration: BoxDecoration(
                image: DecorationImage(
                    image: AssetImage('assets/images/button_blue.png'),
                    fit: BoxFit.fill),
              ),
              alignment: Alignment.center,
              child: CommUtils.getTextGame(
                context,
                13,
                S.of(context).skip_("($CurrentLevel/3)"),
                colorList[0],
                colorList[1],
              ),
            ),
          ),
        ],
      ),
    );
  }

  void getRoundList() {
    rondowRemowMap.clear();
    _randowList.clear();
//第一个
    int fisrtPostion = 7;

    List<List<int>>? shape = BLOCK_SHAPES[fisrtPostion][2];

    List<List<BlockBean>> initialRandom = [];
    for (int i = 0; i < shape.length; i++) {
      List<BlockBean> newList = [];
      for (int j = 0; j < shape[i].length; j++) {
        BlockBean bean = BlockBean();
        bean.normal = shape[i][j];
        if (shape[i][j] == 1) {
          bean.normal = 2;
          bean.img = "assets/images/square.png";
        }

        newList.add(bean);
      }
      initialRandom.add(newList);
    }

    _randowList.add(Block(initialRandom, 0, fisrtPostion));
    _randowList[0].drag = 1; //不允许拖动

    //第二个
    int secondPositon = 0;
    List<List<int>>? shape2 = BLOCK_SHAPES[secondPositon][0];
    List<List<BlockBean>> initialRandom2 = [];
    for (int i = 0; i < shape2.length; i++) {
      List<BlockBean> newList = [];
      for (int j = 0; j < shape2[i].length; j++) {
        BlockBean bean = BlockBean();
        bean.normal = shape2[i][j];
        if (shape2[i][j] == 1) {
          bean.img = "assets/images/square.png";
        }
        newList.add(bean);
      }
      initialRandom2.add(newList);
    }

    _randowList.add(Block(initialRandom2, 0, secondPositon));

    //第三个
    int thirdPositon = 8;
    // print("随机3:" + i3.toString());
    List<List<int>>? shape3 = BLOCK_SHAPES[thirdPositon][2];

    List<List<BlockBean>> initialRandom3 = [];
    for (int i = 0; i < shape3.length; i++) {
      List<BlockBean> newList = [];
      for (int j = 0; j < shape3[i].length; j++) {
        BlockBean bean = BlockBean();
        bean.normal = shape3[i][j];
        if (shape3[i][j] == 1) {
          bean.normal = 2;
          bean.img = "assets/images/square.png";
        }

        newList.add(bean);
      }
      initialRandom3.add(newList);
    }

    _randowList.add(Block(initialRandom3, 0, thirdPositon));
    _randowList[2].drag = 1; //不允许拖动
  }

  int onclickPositon = -1; //触摸的positon

/**
 * 底部三个随机    底部三个图标不能再下去了，底部始终有空白 crossAxisCount: 2,就可以到底部，不知道怎么设置
 */
  Widget _createGridView(double screenhight, double screenwight) {
    return GridView.builder(
      itemCount: _randowList.length,
      shrinkWrap: true,
      padding: EdgeInsets.only(top: 0),
      physics: NeverScrollableScrollPhysics(), //触摸可以
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 3,
        //  mainAxisSpacing: ScreenUtil().setHeight(10), //每行间距
        //  crossAxisSpacing: ScreenUtil().setWidth(10), //交叉轴每行间距
      ),
      itemBuilder: (context, index) {
        //隨機初始化

        List<List<BlockBean>> initialRandom = [];
        for (int i = 0; i < maxHight; i++) {
          initialRandom.add(
            List.filled(maxWidth, BlockBean()),
          );
        }

        for (int i = 0; i < _randowList[index].shape.length; i++) {
          for (int j = 0; j < _randowList[index].shape[i].length; j++) {
            initialRandom[i][j] = _randowList[index].shape[i][j];
          }
        }
        //   return _randowList[index].drag!=0?Text("牛逼") :

        return Draggable<Block>(
          //可以同时拖拽个数
          maxSimultaneousDrags: _randowList[index].drag == 0 ? 1 : 0, //等于0时允许拖
          // 当前组件的数据
          data: _randowList[index],
          feedback: getItem(initialRandom, FixCount1, true, index),
          //拖动过程中，在原来位置停留的Widget，设定这个可以保留原本位置的残影，如果不需要可以直接设置为Container()
          childWhenDragging: Container(),
          child: getItem(initialRandom, FixCount5, false, index),
          onDragStarted: () {
            onclickPositon = index;
          },

          //   ignoringFeedbackSemantics: false,
          onDragEnd: (DraggableDetails details) {
            scoreChangelist.clear();
            if (bgChangelist.length > 0) {
              final i = math.Random().nextInt(inputboardList.length);
              AudioUtils.getInstance()?.play(inputboardList[i]);
              setState(() {
                //证明开始符合填充逻辑  ,此逻辑更改棋盘的填充背景
                for (int i = 0; i < bgChangelist.length; i++) {
                  HashMap map = bgChangelist[i];
                  int xpositon = map.keys.first;
                  //  print("横向索引:${map.keys.first}");
                  // print("shu索引:${map.values.first.toString()}");
                  HashMap<int, BlockBean> map2 = map.values.first;
                  int ypositon = map2.keys.first;
                  //这里只需替换这两个即可，不能全部替换。不然默认棋盘图片也被替换了。
                  _data[xpositon][ypositon].normal = map2.values.first.normal;
                  _data[xpositon][ypositon].img = map2.values.first.img;
                }
                //目的是为了记录当前拖动方块的 ,所以可以为任意值。
                rondowRemowMap[onclickPositon] = "ddddd";
              });

              clearMap();
              onclickPositon = -1;

              double leftx = 0;
              double bottomy = 0;
              double size = 0;
              // 棋盘的坐标值
              RenderBox? renderBox =
                  anchorKey.currentContext?.findRenderObject() as RenderBox?;
              Offset? boardoffset = renderBox?.localToGlobal(Offset.zero);
              var boardoffsetSize = renderBox?.size;

              //每个格子的宽度
              size = CommUtils.getSize(context).height;
              //   double halfSzie = size * 1 / 3;
              leftx = boardoffset!.dx;
              //棋盘最底部的离窗口底部的距离
              bottomy = CommUtils.getHeight(context) -
                  (boardoffsetSize!.height + boardoffset.dy);
              
               CurrentLevel = CurrentLevel! + 1;

              if (CurrentLevel == 2) {
                //横排
                int x = 4;
                double y2 = bottomy + ((8 - x) * size);
                //查询这条横排上是否都有方格填满
                for (int i = 0; i < GAME_PAD_MATRIX_W; i++) {
                  _addShowList(0, Offset(leftx + i * size, y2));
                }
              } else if (CurrentLevel == 3) {
                //竖排
                print("竖排");
                int y = 4;
                double x2 = leftx + y * size;
                for (int i = 0; i < GAME_PAD_MATRIX_W; i++) {
                  _addShowList(0, Offset(x2, bottomy + i * size));
                }
              } else {
                print("九宫格");
                _addNiceList(3, 6, 3, 6);
              }

              setState(() {});
              SpUtils.getInstance()?.setInt(AppConst.fisrt, CurrentLevel!);
              Future.delayed(Duration(milliseconds: 700), () {
                //延迟下，以免消分动画还没完，就刷新布局棋盘了
                if (CurrentLevel! > 3) {
                  Navigator.pop(context);
                  startPageDown2(
                    context,
                    GamePage(
                      isContinue: false,
                      isFisrt: true,
                    ),
                  );
                } else {
                  final I2 = math.Random().nextInt(getSoreList.length);
                  AudioUtils.getInstance()?.play(getSoreList[I2]);
                  startNewGame();
                  setState(() {});
                }
              });
            }
          },
          onDragCompleted: () {
            // print("手指放开时进入棋盘了结束.");
          },
          onDraggableCanceled: (Velocity velocity, Offset offset) {
            // print("手指放开时没有进入棋盘结束");
          },

          onDragUpdate: (DragUpdateDetails details) {
            //固定的棋盘
            RenderBox? renderBox =
                anchorKey.currentContext?.findRenderObject() as RenderBox?;
            Offset? boardoffset = renderBox?.localToGlobal(Offset.zero);

            var boardoffsetSize = renderBox?.size;

            //拖动时
            RenderBox? renderBox2 =
                anchorKey2.currentContext?.findRenderObject() as RenderBox?;
            Offset? randomOffset = renderBox2?.localToGlobal(Offset.zero);
            if (boardoffset != null && randomOffset != null) {
              //  print("棋盘上边固定.${boardoffset.dy}"); //有内边句，加上
              double boxhight = CommUtils.getSize(context).height;
              // //棋盘topY坐标 算法 : 棋盘y坐标-每个方块一半  目的拖动进入棋盘一半就要执行代码
              double boardTopY = boardoffset.dy - (boxhight * 1 / 2);

              //棋盘最底部的y坐标值 算法：棋盘高度+y坐标值==棋盘最底部到屏幕最顶部的y坐标值   .-每个格子的一半  目的拖动进入棋盘一半就要执行代码
              double boarbBottonY =
                  boardoffsetSize!.height + boardoffset.dy - (boxhight * 1 / 2);
              // print("下边固定y坐标." + boarbBottonY.toString());

              //    print("移动的高." + (randomOffset.dy).toString());
              //   print("棋盘底部高:${boardTopY}");
              //棋盘右边X坐标 算法   棋盘宽度+棋盘的x
              double boarbrightX =
                  boardoffsetSize.width + boardoffset.dx - (boxhight * 1 / 2);
              //移动坐标在棋盘内
              if (randomOffset.dy >= boardTopY &&
                  randomOffset.dy <= boarbBottonY &&
                  randomOffset.dx >= 0 &&
                  randomOffset.dx <= boarbrightX) {
                //2拿纵向索引
                int y = -1;
                if (randomOffset.dx < boardoffset.dx) {
                  //从棋盘左边进入
                  if (randomOffset.dx >= boardoffset.dx - (boxhight * 1 / 2)) {
                    y = 0;
                  }
                } else {
                  double padingx = randomOffset.dx - screenwight * 0.03;

                  if (padingx >= 0) {
                    double newx = padingx / boxhight;
                    y = newx.toInt(); //不要四舍五入了，否则从右边进入一半就没蒙版效果了
                    if (y > 8) {
                      y == 8;
                    }
                    //    print("纵向坐标值:" + y.toString());
                  }
                }

                int x = -1;
                //3拿排索引
                if (randomOffset.dy < boardoffset.dy) {
                  //拖动的在棋盘顶部
                  if (randomOffset.dy >= boardoffset.dy - (boxhight * 1 / 2)) {
                    x = 0;
                  }
                } else {
                  //拖动的在棋盘中间
                  double toppading = randomOffset.dy - boardoffset.dy;
                  if (toppading >= 0) {
                    double newy = toppading / boxhight;
                    x = newy.round(); //四舍5入

                    if (x > 8) {
                      x == 8;
                    }
                    //   print("横向坐标值:" + x.toString());
                  }
                }

                if (x == 4 && y == 4) {
                  Block? block = _randowList[onclickPositon]; //当前拖动的方块
                  List<List<BlockBean>> currentlist = block.shape;
                  bool isBack = false;
                  clearMap();
                  for (int i = 0; i < currentlist.length; i++) {
                    //i固定为 0》1,2
                    //随图案是一个二维数组

                    for (int j = 0; j < currentlist[i].length; j++) {
                      if (currentlist[i][j].normal == 1) {
                        //当前拖动的方块
                        //   print("拖动方块坐标值:" + i.toString() + "," + j.toString());

                        int newx = x + i; //X拖动木块的最左边所在索引

                        int newy = y + j; //Y拖动木块的最上边所在索引

                        if (newx > GAME_PAD_MATRIX_H - 1) {
                          clearMap();
                          //只要有一个有方块，就不成立，
                          isBack = true;
                          break;
                          //证明拖动方块有牌数在棋盘的底部外面
                          //   print("没有合适的排超过屏幕");
                        } else if (newy > GAME_PAD_MATRIX_W - 1) {
                          clearMap();
                          //只要有一个有方块，就不成立，
                          isBack = true;
                          break;
                          //证明拖动方块有牌数在棋盘的右边外面
                          //  print("没有y合适的竖超过外面");
                        } else {
                          //正常逻辑
                          BlockBean dataBean = _data[newx][newy];
                          if (dataBean.normal != 1) {
                            //虚拟添加此位置的方格填充状态，方便下一步计算满足消分的蒙版效果
                            mengdata[newx][newy].normal = 1;

                            //给将要满足消分的方格添加蒙版，
                            // List<List<BlockBean>> newdata = _data;
                            //此方格没有模块可以添加
                            //棋盘的横索引int
                            HashMap<int, HashMap<int, BlockBean>> acrosslMap =
                                HashMap();
                            //棋盘的竖索引int
                            HashMap<int, BlockBean> map = HashMap();
                            map[newy] = currentlist[i][j]; //树索引
                            acrosslMap[newx] = map; //横索引
                            bgChangelist.add(acrosslMap);
                          } else {
                            clearMap();
                            //只要有一个有方块，就不成立，
                            isBack = true;
                            break;
                          }

                          // print("正常坐标:" +
                          //     newx.toString() +
                          //     "=" +
                          //     dataBean.img +
                          //     ",,," +
                          //     newy.toString() +
                          //     "=" +
                          //     dataBean.img);

                        }

                        // print("加后:" + newx.toString() + "," + newy.toString());

                      }
                    } //内循环
                    if (isBack) {
                      clearMap();
                      break;
                    }
                  } //外循环

                } else {
                  clearMap();
                }

                //拖动时在棋盘内的逻辑
              } else {
                //拖动时在棋盘外的逻辑
                clearMap();
              }

              //如果允许放入格子的话 ，查询是否可以消分了。
              if (bgChangelist.length > 0) {
                addScore(false, mengdata);
              }

              setState(() {});
            }
          },
        );
      },
    );
  }

  /**
 * 添加九宫格 iCount 
 */
  void _addNiceList(int yStart, int yEnd, int iStart, int iEnd) {
    RenderBox? renderBox =
        anchorKey.currentContext?.findRenderObject() as RenderBox?;
    Offset? boardoffset = renderBox?.localToGlobal(Offset.zero);
    var boardoffsetSize = renderBox?.size;
    //每个格子的宽度
    double size = CommUtils.getSize(context).height;
    double leftx = boardoffset!.dx;
    //棋盘最底部的离窗口底部的距离
    double bottomy = CommUtils.getHeight(context) -
        (boardoffsetSize!.height + boardoffset.dy);
    for (int i = yStart; i < yEnd; i++) {
      for (int y = iStart; y < iEnd; y++) {
        _addShowList(3, Offset(leftx + i * size, bottomy + ((8 - y) * size)));
      }
    }
  }

  /**
   * 添加消分动销
   */
  void _addShowList(int type, Offset offset) {
    var popBean = PopBean();
    popBean.type = type;
    // 横排的话底边距不变。
    popBean.offset = offset;
    addshow.add(popBean);
  }

  //消分弹窗
  List<PopBean> addshow = [];
  /**
   *  给将要待消分格子添加蒙版 isgetScore=tue拖动的时候
   */
  int addScore(bool isgetScore, List<List<BlockBean>> datas) {
    int currentIntegral1 = 0; //横竖排当前积分
    //拖动的时候，把9个消分中格子晴空
    xtop1.clear();
    xtop2.clear();
    xtop3.clear();
    xmiddle1.clear();
    xmiddle2.clear();
    xmiddle3.clear();
    xbottom1.clear();
    xbottom2.clear();
    xbottom3.clear();

    //能填充下就查询
    for (int x = 0; x < GAME_PAD_MATRIX_H; x++) {
      //竖线索引
      int xcount = 0;
      int threeCount = 0;
      for (int y = 0; y < GAME_PAD_MATRIX_W; y++) {
        if (y == 0 || y == 3 || y == 6) {
          //走到9个宫格的开头竖索引，清空
          threeCount = 0;
        }

        if (datas[x][y].normal == 1) {
          xcount = xcount + 1;
          //第一竖
          if (y >= 0 && y <= 2) {
            threeCount = threeCount + 1;
            if (threeCount == 3) {
              if (x >= 0 && x <= 2) {
                xtop1[x] = y;
              } else if (x >= 3 && x <= 5) {
                xmiddle1[x] = y;
              } else if (x >= 6 && x <= 8) {
                xbottom1[x] = y;
              }
            }
            //第2竖
          } else if (y >= 3 && y <= 5) {
            threeCount = threeCount + 1;
            if (threeCount == 3) {
              if (x >= 0 && x <= 2) {
                xtop2[x] = y;
              } else if (x >= 3 && x <= 5) {
                xmiddle2[x] = y;
              } else if (x >= 6 && x <= 8) {
                xbottom2[x] = y;
              }
            }
            //第3竖
          } else if (y >= 6 && y <= 8) {
            threeCount = threeCount + 1;
            if (threeCount == 3) {
              if (x >= 0 && x <= 2) {
                xtop3[x] = y;
              } else if (x >= 3 && x <= 5) {
                xmiddle3[x] = y;
              } else if (x >= 6 && x <= 8) {
                xbottom3[x] = y;
              }
            }
          }

          if (xcount == GAME_PAD_MATRIX_W) {
            //查询这条横排上是否都有方格填满
            for (int i = 0; i < GAME_PAD_MATRIX_W; i++) {
              datas[x][i].normal = 2;
              datas[x][i].eliminationEffect = 1;
              //11111横排添加蒙版
              addScoreMeng(isgetScore, x, i, datas);
            }
          }
        } else {
          datas[x][y].eliminationEffect = 0;
          datas[x][y].normal = 0;
        }
      }
    }

    // 查询这条竖上是否都有方格填满
    for (int y = 0; y < GAME_PAD_MATRIX_W; y++) {
      //竖线索引
      int xcount = 0;
      for (int x = 0; x < GAME_PAD_MATRIX_H; x++) {
        //1.检查竖型是否满足

        if (datas[x][y].normal != 0) {
          //因为上面做横向判断可能变成2，所以只要不等于0就满足
          xcount = xcount + 1;
          if (xcount == GAME_PAD_MATRIX_H) {
            //满足竖排排消状态
            currentIntegral1 = currentIntegral1 + 1;
            for (int i = 0; i < GAME_PAD_MATRIX_W; i++) {
              datas[i][y].normal = 2;
              datas[i][y].eliminationEffect = 1;
              //22222竖添加蒙版
              addScoreMeng(isgetScore, i, y, datas);
            }
          }
        } else {
          datas[x][y].normal = 0;
          datas[x][y].eliminationEffect = 0;
        }

        //2.检查9个小格子
        if (datas[y][x].normal != 0) {
          //因为是9宫格，所以这里可以写死，如果棋盘宽度和高度不一样，就不能用此方法了
          //第一竖
          if (x >= 0 && x <= 2) {
            if (xtop1.length > 2) {
              if (y >= 0 && y <= 2) {
                //0-行索引
                print("xop1");
                datas = changData(isgetScore, y, x, datas);
              }
            }
            if (xmiddle1.length > 2) {
              if (y >= 3 && y <= 5) {
                //3-5行
                print("middle11");
                datas = changData(isgetScore, y, x, datas);
              }
            }

            if (xbottom1.length > 2) {
              if (y >= 6 && y <= 8) {
                //6-8行
                print("xbottom1");
                datas = changData(isgetScore, y, x, datas);
              }
            }
            //第二竖
          } else if (x >= 3 && x <= 5) {
            if (xtop2.length > 2) {
              if (y >= 0 && y <= 2) {
                print("xop2");
                datas = changData(isgetScore, y, x, datas);
              }
            }
            if (xmiddle2.length > 2) {
              if (y >= 3 && y <= 5) {
                print("middle2");
                datas = changData(isgetScore, y, x, datas);
              }
            }

            if (xbottom2.length > 2) {
              if (y >= 6 && y <= 8) {
                print("xbottom2");
                datas = changData(isgetScore, y, x, datas);
              }
            }
            //第三竖
          } else if (x >= 6 && x <= 8) {
            if (xtop3.length > 2) {
              if (y >= 0 && y <= 2) {
                print("xop3");
                datas = changData(isgetScore, y, x, datas);
              }
            }
            if (xmiddle3.length > 2) {
              if (y >= 3 && y <= 5) {
                print("middle3");
                datas = changData(isgetScore, y, x, datas);
              }
            }

            if (xbottom3.length > 2) {
              if (y >= 6 && y <= 8) {
                print("xbottom3");
                datas = changData(isgetScore, y, x, datas);
              }
            }
          }
        }
      }
    }

    if (isgetScore) {
      _data = datas;
      mengdata = CommUtils.copyWithList(_data);
    }

    return currentIntegral1;
  }

  /**
   * 增加分数蒙版
   */
  void addScoreMeng(
      bool isgetScore, int x, int y, List<List<BlockBean>> datas) {
    //拖动时，添加蒙版
    if (isgetScore == false) {
      HashMap<int, HashMap<int, BlockBean>> acrosslMap = HashMap();
      //棋盘的竖索引int
      HashMap<int, BlockBean> map = HashMap();
      map[y] = datas[x][y]; //树索引
      acrosslMap[x] = map; //横索引
      scoreChangelist.add(acrosslMap);
    }
  }

  List<List<BlockBean>> changData(
      bool isgetScore, int x, int y, List<List<BlockBean>> datas) {
    if (isgetScore) {
      datas[x][y].normal = 2;
      datas[x][y].eliminationEffect = 1;
    } else {
      //33333竖9个九宫格蒙版
      addScoreMeng(isgetScore, x, y, datas);
    }

    return datas;
  }

  //连击次数
  int adjacentMultiple = 0;

  //满足消分的总个数
  // int fractionCount = 0;

  void clearMap() {
    //  fractionCount = 0;
    bgChangelist.clear();
    scoreChangelist.clear();
    mengdata = CommUtils.copyWithList(_data);
    xtop1.clear();
    xtop2.clear();
    xtop3.clear();
    xmiddle1.clear();
    xmiddle2.clear();
    xmiddle3.clear();
    xbottom1.clear();
    xbottom2.clear();
    xbottom3.clear();
  }

  //相邻的九宫格，下次要*2
  bool xtop1Have = false;
  bool xtop2Have = false;
  bool xtop3Have = false;
  bool xmiddle1Have = false;
  bool xmiddle2Have = false;
  bool xmiddle3Have = false;
  bool xbottom1Have = false;
  bool xbottom2Have = false;
  bool xbottom3Have = false;

  HashMap<int, int> xtop1 = HashMap();
  HashMap<int, int> xtop2 = HashMap();
  HashMap<int, int> xtop3 = HashMap();
  HashMap<int, int> xmiddle1 = HashMap();
  HashMap<int, int> xmiddle2 = HashMap();
  HashMap<int, int> xmiddle3 = HashMap();
  HashMap<int, int> xbottom1 = HashMap();
  HashMap<int, int> xbottom2 = HashMap();
  HashMap<int, int> xbottom3 = HashMap();

  ////给将要满足填充条件的格子添加蒙版。。  int 棋盘的行索引  ，  int 棋盘的竖索引
  List<HashMap<int, HashMap<int, BlockBean>>> bgChangelist = [];

  //给将要满足消分条件的格子添加蒙版。  int 棋盘的行索引  ，  int 棋盘的竖索引
  List<HashMap<int, HashMap<int, BlockBean>>> scoreChangelist = [];

  HashMap<int, String> rondowRemowMap =
      HashMap(); //下方隐藏的方块。 临时保存随机图案放入棋盘后，以便将随机团隐藏掉，

  //满足消分，  int 棋盘的行索引  ，  int 棋盘的竖索引
  HashMap<int, HashMap<int, BlockBean>> fractionMap = HashMap();

/**
 *   fixCount 比率  每个随机图片的排列方式 iskey 放大
 */

  Widget getItem(List<List<BlockBean>> initialRandom, double fixCount,
      bool iskey, int currentPostion) {
    if (rondowRemowMap[currentPostion] != null) {
      return Container();
    } else {
      return getItem2(initialRandom, fixCount, iskey);
    }
  }

  Widget getItem2(
      List<List<BlockBean>> initialRandom, double fixCount, bool iskey) {
    var width = CommUtils.getWidth(context);
    if (iskey) {
      //放大的随机图
      return Container(
        padding: EdgeInsets.only(
          left: 10,
          top: 0,
          right: 5,
        ),
        child: Column(
          key: anchorKey2,
          //3竖
          children: initialRandom.map((list) {
            return Row(
              //2排
              children: list.map((b) {
                return randomBrik.normal(b, fixCount);
              }).toList(),
            );
          }).toList(),
        ),
      );
    } else {
      return Padding(
          padding: EdgeInsets.only(
            left: 30, //这里写死，为了web拖动适配
          ),
          child: Column(
            children: [
              Expanded(child: SizedBox()),
              Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                //3竖
                children: initialRandom.map((list) {
                  return Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    //2排
                    children: list.map((b) {
                      return randomBrik.normal(b, fixCount);
                    }).toList(),
                  );
                }).toList(),
              ),
            ],
          ));
    }
  }
}

class TextTween extends Tween<String> {
  TextTween({String? end = ''}) : super(begin: '', end: end);

  @override
  String lerp(double t) {
    // 在动画过程中 t 的值是从 0 到 1
    var cutoff = (end!.length * t).round();
    // 返回动画时钟t时刻 对应的文字。
    return end!.substring(0, cutoff);
  }
}
